﻿
using S7Cat.Tools;
using System.Net.Sockets;

namespace S7Cat.Protocol
{
    internal static class TSDU
    {
        /// <summary>
        /// Reads the full COTP TSDU (Transport service data unit)
        /// See: https://tools.ietf.org/html/rfc905
        /// </summary>
        /// <param name="stream">The stream to read from</param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the asynchronous operation.</param>
        /// <returns>Data in TSDU</returns>
        //public static async Task<MemoryOwner<byte>> ReadAsync(NetworkStream stream, CancellationToken cancellationToken)
        //{
        //    var segment = await TPDU.ReadAsync(stream, cancellationToken).ConfigureAwait(false);

        //    bool isLastUnit = segment.IsLastUnit;

        //    while (!isLastUnit)
        //    {
        //        var newSegment = await TPDU.ReadAsync(stream, cancellationToken).ConfigureAwait(false);
        //        segment.Data += newSegment.Data;
        //        newSegment.Data.Dispose();
        //        isLastUnit = newSegment.IsLastUnit;
        //    }

        //    return segment.Data;
        //}

        /// <summary>
        /// Reads the full COTP TSDU (Transport service data unit)
        /// See: https://tools.ietf.org/html/rfc905
        /// </summary>
        /// <param name="stream">The stream to read from</param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the asynchronous operation.</param>
        /// <returns>Data in TSDU</returns>
        public static async Task<MemoryOwner<byte>> ReadAsync(NetworkStream stream, CancellationToken cancellationToken)
        {
            var (data, isLastUnit) = await TPDU.ReadDataAsync(stream, cancellationToken).ConfigureAwait(false);

            if (isLastUnit)
            {
                return data;
            }

            while (true)
            {
                var (newData, isLast) = await TPDU.ReadDataAsync(stream, cancellationToken).ConfigureAwait(false);
                data += newData;
                newData.Dispose();
                if (isLast)
                {
                    return data;
                }
            }
        }
    }
}
